﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using BoolanElement;
using BoolanElement.Storage;
using BoolanSlide.Document.Format.Helper;
using Windows.Data.Xml.Dom;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Media.Imaging;

namespace BoolanSlide.FileStruct
{
    public class BooDocumentInMemory
    {
        public BPTFileBlock summaryBlock;
        public List<BPTFileBlock> ImageBlocks;
        public List<BPTFileBlock> SlideBlocks;
        public BPTFileBlock ThumbBlock;

        public String FileName;

        public BooDocumentInMemory()
        {
            summaryBlock = new BPTFileBlock();
            summaryBlock.GroupName = "base";

            ImageBlocks = new List<BPTFileBlock>();

            SlideBlocks = new List<BPTFileBlock>();

            ThumbBlock = new BPTFileBlock();
            ThumbBlock.GroupName = "thumb";
        }

        public async Task<BitmapImage> GetImage(string name)
        {
            BitmapImage image = null;
            foreach (var item in ImageBlocks)
            {
                if (item.FileName == name)
                {
                    using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
                    {
                        using (DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0)))
                        {
                            writer.WriteBytes(item.ByteData);
                            await writer.StoreAsync();
                            await writer.FlushAsync();
                            image = new BitmapImage();
                            image.SetSource(stream);
                        }
                    }
                }
            }
            return image;
        }

        public async Task<StorageFile> GetImageFile(string name)
        {
            StorageFolder imageFolder = await BooUtility.GetFolderFromDocumentFolderAsync(BooDocumentHelper.ImageTmpFolder);
            StorageFile image = null;
            foreach (var item in ImageBlocks)
            {
                if (item.FileName == name)
                {
                    image = await imageFolder.CreateFileAsync(item.FileName,CreationCollisionOption.GenerateUniqueName);
                    using (IRandomAccessStream stream = await image.OpenAsync(FileAccessMode.ReadWrite))
                    {
                        using (DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0)))
                        {
                            writer.WriteBytes(item.ByteData);
                            await writer.StoreAsync();
                            await writer.FlushAsync();
                        }
                    }
                }
            }
            return image;
        }

        public async Task<bool> CreateImageFile()
        {
            StorageFolder imageFolder = BooDocumentFolderInformation.ImageResources;
            await BooUtility.DeleteFolderContent(imageFolder);
            StorageFile image = null;
            foreach (var item in ImageBlocks)
            {
                try
                {
                    image = await imageFolder.CreateFileAsync(item.FileName);
                    using (IRandomAccessStream stream = await image.OpenAsync(FileAccessMode.ReadWrite))
                    {
                        using (DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0)))
                        {
                            writer.WriteBytes(item.ByteData);
                            await writer.StoreAsync();
                            await writer.FlushAsync();
                        }
                    }
                }
                catch (Exception exp)
                {
                    continue;
                }
            }
            return false;
        }

        public async Task<bool> CreateImageFile(StorageFolder folder)
        {
            //danger!!!
           // await BooUtility.DeleteFolderContent(folder);
            StorageFile image = null;
            foreach (var item in ImageBlocks)
            {
                try
                {
                    image = await folder.CreateFileAsync(item.FileName);
                    using (IRandomAccessStream stream = await image.OpenAsync(FileAccessMode.ReadWrite))
                    {
                        using (DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0)))
                        {
                            writer.WriteBytes(item.ByteData);
                            await writer.StoreAsync();
                            await writer.FlushAsync();
                        }
                    }
                }
                catch (Exception exp)
                {
                    continue;
                }
            }
            return false;
        }

        public async Task<XmlDocument> GetSummary()
        {
            string xml = System.Text.Encoding.UTF8.GetString(summaryBlock.ByteData, 0, summaryBlock.ByteData.Count());
           
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            return doc;
        }

        public async Task<List<BooSlide>> GetSlide()
        {
            List<BooSlide> slides = new List<BooSlide>();
            foreach (var slide in SlideBlocks)
            {
                slides.Add(await GetSlide(slide));
            }
            return slides;
        }

        public async Task<BooSlide> GetSlide(BPTFileBlock block)
        {
            string xml = System.Text.Encoding.UTF8.GetString(block.ByteData, 0, block.ByteData.Count());
            XDocument document = XDocument.Parse(xml, LoadOptions.PreserveWhitespace);
            BooSlide slide = BooSlideHelper.GenerateSlide(document);
            return slide;
        }

    }
}
